﻿module Sustainalytics.Portfolio {

    import Common = Sustainalytics.Common;
    import Pager = Sustainalytics.Pager;
    import LRTM = Sustainalytics.LRTM;
    import Company = Sustainalytics.Company;
    import PortfolioMatchType = Sustainalytics.Portfolio.PortfolioMatchType;

    // ShowErrorsInModal controller
    export class PortfolioMatchesModalController {

        public portfolioCompanyFilter: PortfolioCompanyFilterDto;

        public orderByColValid: string;
        public orderByAscValid: boolean;
        public orderByColInvalid: string;
        public orderByAscInvalid: boolean;
        private $routeParams: any;
        public portfolioValidMatchesList: Sustainalytics.Portfolio.PortfolioValidMatchesDto[];
        public portfolioInvalidMatchesList: Sustainalytics.Portfolio.PortfolioInvalidMatchesDto[];
        public isEditValidMatches: boolean;
        private accountId: string;
        private userId: string;
        // total number of portfolios
        public portfolioCount: number;
        private scopeDestroyed: boolean;
        public portfolioValidMatchesCount: number;
        public portfolioInvalidMatchesCount: number;
        public isRenamingPortfolioName: boolean;
        //public portfolio: PortfolioDto;
        public newPortfolioName: string;
        public newSecurityWeightValue: number;
        public currentSecurityWeightObjectChangedId: string;
        public currentValidMatchesPage: number;
        public currentInvalidMatchesPage: number;
        public updatedSecurityWeightValue: number;

        public pageSize: number;
        public total: number;
        private lrtmservice: LRTM.LongRunningTaskManagerService;


        // Ctor.
        constructor(
            private $rootScope: ng.IScope,
            private $scope: ng.IScope,
            private $q: ng.IQService,
            private $location: ng.ILocationService,
            private notificationFactory: Common.INotificationFactory,
            private staticObjects: Common.IStaticObjects,
            private RoutingService: Routing.IRoutingService,
            private PortfolioCompanyService: PortfolioCompanyService,
            private $modal: Common.IModal,
            private $modalInstance: Common.IModalInstance,
            private portfolioId: string,
            private portfolioName: string,
            private errors: string,
            private PortfolioService: PortfolioService,
            private LongRunningTaskManagerService: LRTM.LongRunningTaskManagerService,
            private listPortfoliosHandler) {

            var ctx = this;
            ctx.$routeParams = ctx.RoutingService.getRouteParams();
            this.staticObjects = staticObjects;

            $scope['portfolioHandler'] = ctx;

            ctx.portfolioCompanyFilter = new PortfolioCompanyFilterDto();

            ctx.orderByColValid = "CompanyNameLowercase";
            ctx.orderByAscValid = true;
            ctx.orderByColInvalid = "DisplayInfo.SecurityIdentifier";
            ctx.orderByAscInvalid = true;

            ctx.accountId = ctx.$rootScope['userInfo'].accountId;
            ctx.userId = ctx.$rootScope['userInfo'].userId;

            this.pageSize = 5;

            ctx.handleScopeDestroyed();

            ctx.getValidMatches(1);
            ctx.getInvalidMatches(1);

            this.currentSecurityWeightObjectChangedId = "";
        }

        public changeIsRenaming() {
            var ctx = this;
            ctx.isRenamingPortfolioName = !ctx.isRenamingPortfolioName;
            ctx.newPortfolioName = ctx.portfolioName;
        }

        public isChangingSecurityWeight(divObjId: string)
        {
            var ctx = this;
            var isEqual = ctx.currentSecurityWeightObjectChangedId == divObjId;
            return isEqual;
        }

        public editSecurityWeight(divObjId: string, securityWeight: number, isEditValidMatches: boolean) {
            var ctx = this;
            if (ctx.currentSecurityWeightObjectChangedId == "") {
                ctx.currentSecurityWeightObjectChangedId = divObjId;
                ctx.updatedSecurityWeightValue = securityWeight;
                ctx.isEditValidMatches = isEditValidMatches;
            }
        }

        public isNumeric(n) {
            return !isNaN(parseFloat(n)) && isFinite(n);
        }

        public updateSecurityWeight(divObjId: string) {
            var ctx = this;
            if (ctx.updatedSecurityWeightValue.toString() == "") {
                var promiseChangeValue = ctx.PortfolioService.updateSecurityWeight(divObjId, null, !ctx.isEditValidMatches);
                promiseChangeValue
                    .then(() => {
                        if (ctx.isEditValidMatches) {
                            ctx.portfolioValidMatchesList.forEach(xxx => {
                                if (xxx.id == divObjId)
                                    xxx.securityWeight = null;
                            });
                        }
                        else {
                            ctx.portfolioInvalidMatchesList.forEach(xxx => {
                                if (xxx.id == divObjId)
                                    xxx.securityWeight = null;
                            });
                        }
                        ctx.doneEditSecurityWeight();
                    })
                    .catch(err => this.notificationFactory.error("Error", "The new security weight value cannot be saved"));
            }
            else {
                var promiseChangeValue = ctx.PortfolioService.updateSecurityWeight(divObjId, ctx.updatedSecurityWeightValue, !ctx.isEditValidMatches);
                promiseChangeValue
                    .then(() => {
                        if (ctx.isEditValidMatches) {
                            ctx.portfolioValidMatchesList.forEach(xxx => {
                                if (xxx.id == divObjId)
                                    xxx.securityWeight = ctx.updatedSecurityWeightValue;
                            });
                        }
                        else {
                            ctx.portfolioInvalidMatchesList.forEach(xxx => {
                                if (xxx.id == divObjId)
                                    xxx.securityWeight = ctx.updatedSecurityWeightValue;
                            });
                        }
                        ctx.doneEditSecurityWeight();
                    })
                    .catch(err => this.notificationFactory.error("Error", "The new security weight value cannot be saved"));
            }
        }

        public doneEditSecurityWeight() {
            var ctx = this;
            ctx.currentSecurityWeightObjectChangedId = "";
        }
        
        public addCompanyToPortfolioMatches(company: Company.CorporateDataExtendedDto) {
            var ctx = this;
            var promise = this.PortfolioCompanyService.addCompanyToPortfolioMatches(this.portfolioName, company.id);

            promise.then((response) => {

                if (response.data && response.data['warningCode'] === 5105) {
                    ctx.notificationFactory.warn(ctx.staticObjects.getMessageByInternalCode(response.data["warningCode"]));
                }
                if (response.data && response.data['warningCode'] === 5107) {
                    ctx.notificationFactory.warn(ctx.staticObjects.getMessageByInternalCode(response.data["warningCode"]));
                }
                if (response.data === "") {
                    this.notificationFactory.success("Succesfully added");
                    this.getValidMatches(this.currentValidMatchesPage);
                }

            });
        }

        private handleScopeDestroyed() {
            var ctx = this;

            // when scope is destroyed
            ctx.$scope.$on('$destroy', function () {
                ctx.scopeDestroyed = true;
            });
        }

        public closeDialog = function () {
            var ctx = this;
            ctx.resultCheck = false;

            var promise = ctx.PortfolioCompanyService.deletePortfolioMatches(this.portfolioName);

            promise.then(() => ctx.$modalInstance.close({ check: ctx.resultCheck }))
                .catch(() => { this.notificationFactory.error("Error", "Matches were not discarded") });
        };

        // order list of portfolios
        public setOrderByColValid(col: string) {

            var ctx = this;

            if (ctx.orderByColValid === col) {
                ctx.orderByAscValid = !ctx.orderByAscValid;
            }
            else {
                ctx.orderByColValid = col;
                ctx.orderByAscValid = true;
            }
            this.getValidMatches(this.currentValidMatchesPage);
        }

        public setOrderByColInvalid(col: string) {

            var ctx = this;

            if (ctx.orderByColInvalid === col) {
                ctx.orderByAscInvalid = !ctx.orderByAscInvalid;
            }
            else {
                ctx.orderByColInvalid = col;
                ctx.orderByAscInvalid = true;
            }
            this.getInvalidMatches(this.currentInvalidMatchesPage);
        }

        public renamePortfolio() {
            var ctx = this;

            if (ctx.portfolioId !== undefined && ctx.portfolioId !== null) {

                var portfolioRename = new PortfolioRenameDto();
                portfolioRename.id = ctx.portfolioId;
                portfolioRename.newPortfolioName = ctx.newPortfolioName;
                portfolioRename.oldPortfolioName = ctx.portfolioName;

                var promiseRename = ctx.PortfolioService.renamePortfolio(portfolioRename);

                promiseRename
                    .then(() => {
                        this.portfolioName = this.newPortfolioName;
                        this.isRenamingPortfolioName = false;
                    })
                    .catch(() => {
                    });
            }
            else {
                var promiseRenameMatches = ctx.PortfolioCompanyService.renamePortfolioMatches(this.portfolioName, this.newPortfolioName);

                promiseRenameMatches
                    .then(() => {
                        this.portfolioName = this.newPortfolioName;
                        this.isRenamingPortfolioName = false;
                    })
                    .catch(() => {
                    });
            }

        }

        



    

        public companyHasSecurity(match: Sustainalytics.Portfolio.PortfolioValidMatchesDto): boolean {
            return PortfolioMatchType.CompanyHasNoSecurity != match.matchType;
                
        }

       public clientHasAccess(match:  Sustainalytics.Portfolio.PortfolioValidMatchesDto) : boolean {
            return PortfolioMatchType.NoAccess != match.matchType;
        }

       public addSecurityToMatched(portfolioMatchId: string, match: UnmatchedInformationDto) {
            if (PortfolioMatchType.CompanyHasNoValidSecurity == match.matchType ||
                PortfolioMatchType.CompanyHasNoSecurity == match.matchType ||
                PortfolioMatchType.NoMatch == match.matchType) {
                this.notificationFactory.warn("Security not valid to be added");
                return;
            }

            if (this.currentInvalidMatchesPage > 1 && this.portfolioInvalidMatchesCount % this.pageSize == 1)
                this.currentInvalidMatchesPage--;

            var addSecurityPromise = this.PortfolioCompanyService.addSecurityToMatched(this.portfolioName, portfolioMatchId);

            this.$q.all([addSecurityPromise])
                .then((data) => {
                    this.getValidMatches(this.currentValidMatchesPage);
                    this.getInvalidMatches(this.currentInvalidMatchesPage);
                });
        }

        public removePortfolioMatch(portfolioMatchId: string) {
            var matchIds = [portfolioMatchId];
            var promise = this.PortfolioCompanyService.deleteSelectedMatches(this.portfolioName, matchIds);

            if (this.currentValidMatchesPage > 1 && this.portfolioValidMatchesCount % this.pageSize == 1)
                this.currentValidMatchesPage--;

            promise.then((data) => {
                this.getValidMatches(this.currentValidMatchesPage);
            });
        }

        public downloadPortfolioMatchedSecurities() {
            var ctx = this;
            var data = {
                portfolioName: ctx.portfolioName,
            };

            var refreshPortfolioGridCallBack = () => ctx.listPortfoliosHandler();

            var promise = ctx.LongRunningTaskManagerService.runTask('Download portfolio matched securities', JSON.stringify(data),
                LRTM.LongRunningTaskTypeEnum.PortfolioMatchedSecuritiesDownload, true, refreshPortfolioGridCallBack);

            promise.then(response => {
                this.notificationFactory.success("Matches were imported");
            })
                .catch(err => this.notificationFactory.error("Error", "Matches were not imported"))
                .finally(() => {
                    ctx.$rootScope['loading'] = false;
                    ctx.$modalInstance.close({ check: true })
                });
        }

        public getValidMatches(page: number) {
            var ctx = this;
            ctx.currentValidMatchesPage = page;
            ctx.$rootScope['loading'] = true;

            var skip = (this.currentValidMatchesPage - 1) * this.pageSize;
            var take = this.pageSize;

            var promiseGet = ctx.PortfolioCompanyService.getValidPortfolioMatches(ctx.portfolioName, skip, take, [ctx.orderByColValid], ctx.orderByAscValid);

            var portfolioCompanyListTemp: Sustainalytics.Portfolio.PortfolioValidMatchesDto[];
            var portfolioCompanyCountTemp: number;

            promiseGet.then(function (lst) {
                portfolioCompanyListTemp = lst.data["portfolioMatches"];
                portfolioCompanyCountTemp = lst.data["portfolioCompanyCount"];
                ctx.portfolioValidMatchesList = portfolioCompanyListTemp;
                ctx.portfolioValidMatchesCount = portfolioCompanyCountTemp;
            })
            .finally(() => ctx.$rootScope['loading'] = false);
        }

        public getInvalidMatches(page: number) {
            var ctx = this;
            ctx.currentInvalidMatchesPage = page;
            ctx.$rootScope['loading'] = true;

            var skip = (this.currentInvalidMatchesPage - 1) * this.pageSize;
            var take = this.pageSize;


            // get portfolio items
            var promiseGet = ctx.PortfolioCompanyService.getInvalidPortfolioMatches(ctx.portfolioName, skip, take, [ctx.orderByColInvalid], ctx.orderByAscInvalid);

            var portfolioCompanyListTemp: Sustainalytics.Portfolio.PortfolioInvalidMatchesDto[];
            var portfolioCompanyCountTemp: number;


            promiseGet.then(function (lst) {
                portfolioCompanyListTemp = lst.data["portfolioMatches"];
                portfolioCompanyCountTemp = lst.data["portfolioCompanyCount"];
                ctx.portfolioInvalidMatchesList = portfolioCompanyListTemp;
                ctx.portfolioInvalidMatchesCount = portfolioCompanyCountTemp;
            })
                .finally(() => ctx.$rootScope['loading'] = false);
        }
    }


    // register controller with News Angular module
    angular.module(portfolioModuleName).controller('PortfolioMatchesModalController',
        ['$rootScope', '$scope', '$q', '$location', 'notificationFactory', 'staticObjects', 'RoutingService',
            'PortfolioCompanyService', '$modal', '$modalInstance', 'portfolioId', 'portfolioName', 'errors', 'PortfolioService', 'LongRunningTaskManagerService', 'listPortfoliosHandler'
            , PortfolioMatchesModalController]);
} 
